home *** CD-ROM | disk | FTP | other *** search
/ Freelog 115 / FreelogNo115-MaiJuin2013.iso / Internet / AvantBrowser / asetup.exe / _data / webkit / resources.pak / Unnamed File 000066.txt < prev    next >
Text File  |  2013-04-03  |  10KB  |  340 lines

  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4.  
  5. cr.define('cr.ui', function() {
  6.   /** @const */ var Event = cr.Event;
  7.   /** @const */ var EventTarget = cr.EventTarget;
  8.  
  9.   /**
  10.    * Creates a new selection model that is to be used with lists.
  11.    *
  12.    * @param {number=} opt_length The number items in the selection.
  13.    *
  14.    * @constructor
  15.    * @extends {!cr.EventTarget}
  16.    */
  17.   function ListSelectionModel(opt_length) {
  18.     this.length_ = opt_length || 0;
  19.     // Even though selectedIndexes_ is really a map we use an array here to get
  20.     // iteration in the order of the indexes.
  21.     this.selectedIndexes_ = [];
  22.  
  23.     // True if any item could be lead or anchor. False if only selected ones.
  24.     this.independentLeadItem_ = !cr.isMac && !cr.isChromeOS;
  25.   }
  26.  
  27.   ListSelectionModel.prototype = {
  28.     __proto__: EventTarget.prototype,
  29.  
  30.     /**
  31.      * The number of items in the model.
  32.      * @type {number}
  33.      */
  34.     get length() {
  35.       return this.length_;
  36.     },
  37.  
  38.     /**
  39.      * The selected indexes.
  40.      * Setter also changes lead and anchor indexes if value list is nonempty.
  41.      * @type {!Array}
  42.      */
  43.     get selectedIndexes() {
  44.       return Object.keys(this.selectedIndexes_).map(Number);
  45.     },
  46.     set selectedIndexes(selectedIndexes) {
  47.       this.beginChange();
  48.       var unselected = {};
  49.       for (var index in this.selectedIndexes_) {
  50.         unselected[index] = true;
  51.       }
  52.  
  53.       for (var i = 0; i < selectedIndexes.length; i++) {
  54.         var index = selectedIndexes[i];
  55.         if (index in this.selectedIndexes_) {
  56.           delete unselected[index];
  57.         } else {
  58.           this.selectedIndexes_[index] = true;
  59.           this.changedIndexes_[index] = true;
  60.         }
  61.       }
  62.  
  63.       for (var index in unselected) {
  64.         delete this.selectedIndexes_[index];
  65.         this.changedIndexes_[index] = false;
  66.       }
  67.  
  68.       if (selectedIndexes.length) {
  69.         this.leadIndex = this.anchorIndex = selectedIndexes[0];
  70.       } else {
  71.         this.leadIndex = this.anchorIndex = -1;
  72.       }
  73.       this.endChange();
  74.     },
  75.  
  76.     /**
  77.      * Convenience getter which returns the first selected index.
  78.      * Setter also changes lead and anchor indexes if value is nonnegative.
  79.      * @type {number}
  80.      */
  81.     get selectedIndex() {
  82.       for (var i in this.selectedIndexes_) {
  83.         return Number(i);
  84.       }
  85.       return -1;
  86.     },
  87.     set selectedIndex(selectedIndex) {
  88.       this.selectedIndexes = selectedIndex != -1 ? [selectedIndex] : [];
  89.     },
  90.  
  91.     /**
  92.      * Returns the last selected index or -1 if no item selected.
  93.      * @type {number}
  94.      */
  95.     get lastSelectedIndex() {
  96.       var result = -1;
  97.       for (var i in this.selectedIndexes_) {
  98.         result = Math.max(result, Number(i));
  99.       }
  100.       return result;
  101.     },
  102.  
  103.     /**
  104.      * Selects a range of indexes, starting with {@code start} and ends with
  105.      * {@code end}.
  106.      * @param {number} start The first index to select.
  107.      * @param {number} end The last index to select.
  108.      */
  109.     selectRange: function(start, end) {
  110.       // Swap if starts comes after end.
  111.       if (start > end) {
  112.         var tmp = start;
  113.         start = end;
  114.         end = tmp;
  115.       }
  116.  
  117.       this.beginChange();
  118.  
  119.       for (var index = start; index != end; index++) {
  120.         this.setIndexSelected(index, true);
  121.       }
  122.       this.setIndexSelected(end, true);
  123.  
  124.       this.endChange();
  125.     },
  126.  
  127.     /**
  128.      * Selects all indexes.
  129.      */
  130.     selectAll: function() {
  131.       this.selectRange(0, this.length - 1);
  132.     },
  133.  
  134.     /**
  135.      * Clears the selection
  136.      */
  137.     clear: function() {
  138.       this.beginChange();
  139.       this.length_ = 0;
  140.       this.anchorIndex = this.leadIndex = -1;
  141.       this.unselectAll();
  142.       this.endChange();
  143.     },
  144.  
  145.     /**
  146.      * Unselects all selected items.
  147.      */
  148.     unselectAll: function() {
  149.       this.beginChange();
  150.       for (var i in this.selectedIndexes_) {
  151.         this.setIndexSelected(i, false);
  152.       }
  153.       this.endChange();
  154.     },
  155.  
  156.     /**
  157.      * Sets the selected state for an index.
  158.      * @param {number} index The index to set the selected state for.
  159.      * @param {boolean} b Whether to select the index or not.
  160.      */
  161.     setIndexSelected: function(index, b) {
  162.       var oldSelected = index in this.selectedIndexes_;
  163.       if (oldSelected == b)
  164.         return;
  165.  
  166.       if (b)
  167.         this.selectedIndexes_[index] = true;
  168.       else
  169.         delete this.selectedIndexes_[index];
  170.  
  171.       this.beginChange();
  172.  
  173.       this.changedIndexes_[index] = b;
  174.  
  175.       // End change dispatches an event which in turn may update the view.
  176.       this.endChange();
  177.     },
  178.  
  179.     /**
  180.      * Whether a given index is selected or not.
  181.      * @param {number} index The index to check.
  182.      * @return {boolean} Whether an index is selected.
  183.      */
  184.     getIndexSelected: function(index) {
  185.       return index in this.selectedIndexes_;
  186.     },
  187.  
  188.     /**
  189.      * This is used to begin batching changes. Call {@code endChange} when you
  190.      * are done making changes.
  191.      */
  192.     beginChange: function() {
  193.       if (!this.changeCount_) {
  194.         this.changeCount_ = 0;
  195.         this.changedIndexes_ = {};
  196.         this.oldLeadIndex_ = this.leadIndex_;
  197.         this.oldAnchorIndex_ = this.anchorIndex_;
  198.       }
  199.       this.changeCount_++;
  200.     },
  201.  
  202.     /**
  203.      * Call this after changes are done and it will dispatch a change event if
  204.      * any changes were actually done.
  205.      */
  206.     endChange: function() {
  207.       this.changeCount_--;
  208.       if (!this.changeCount_) {
  209.         // Calls delayed |dispatchPropertyChange|s, only when |leadIndex| or
  210.         // |anchorIndex| has been actually changed in the batch.
  211.         this.leadIndex_ = this.adjustIndex_(this.leadIndex_);
  212.         if (this.leadIndex_ != this.oldLeadIndex_) {
  213.           cr.dispatchPropertyChange(this, 'leadIndex',
  214.                                     this.leadIndex_, this.oldLeadIndex_);
  215.         }
  216.         this.oldLeadIndex_ = null;
  217.  
  218.         this.anchorIndex_ = this.adjustIndex_(this.anchorIndex_);
  219.         if (this.anchorIndex_ != this.oldAnchorIndex_) {
  220.           cr.dispatchPropertyChange(this, 'anchorIndex',
  221.                                     this.anchorIndex_, this.oldAnchorIndex_);
  222.         }
  223.         this.oldAnchorIndex_ = null;
  224.  
  225.         var indexes = Object.keys(this.changedIndexes_);
  226.         if (indexes.length) {
  227.           var e = new Event('change');
  228.           e.changes = indexes.map(function(index) {
  229.             return {
  230.               index: Number(index),
  231.               selected: this.changedIndexes_[index]
  232.             };
  233.           }, this);
  234.           this.dispatchEvent(e);
  235.         }
  236.         this.changedIndexes_ = {};
  237.       }
  238.     },
  239.  
  240.     leadIndex_: -1,
  241.     oldLeadIndex_: null,
  242.  
  243.     /**
  244.      * The leadIndex is used with multiple selection and it is the index that
  245.      * the user is moving using the arrow keys.
  246.      * @type {number}
  247.      */
  248.     get leadIndex() {
  249.       return this.leadIndex_;
  250.     },
  251.     set leadIndex(leadIndex) {
  252.       var oldValue = this.leadIndex_;
  253.       var newValue = this.adjustIndex_(leadIndex);
  254.       this.leadIndex_ = newValue;
  255.       // Delays the call of dispatchPropertyChange if batch is running.
  256.       if (!this.changeCount_ && newValue != oldValue)
  257.         cr.dispatchPropertyChange(this, 'leadIndex', newValue, oldValue);
  258.     },
  259.  
  260.     anchorIndex_: -1,
  261.     oldAnchorIndex_: null,
  262.  
  263.     /**
  264.      * The anchorIndex is used with multiple selection.
  265.      * @type {number}
  266.      */
  267.     get anchorIndex() {
  268.       return this.anchorIndex_;
  269.     },
  270.     set anchorIndex(anchorIndex) {
  271.       var oldValue = this.anchorIndex_;
  272.       var newValue = this.adjustIndex_(anchorIndex);
  273.       this.anchorIndex_ = newValue;
  274.       // Delays the call of dispatchPropertyChange if batch is running.
  275.       if (!this.changeCount_ && newValue != oldValue)
  276.         cr.dispatchPropertyChange(this, 'anchorIndex', newValue, oldValue);
  277.     },
  278.  
  279.     /**
  280.      * Helper method that adjustes a value before assiging it to leadIndex or
  281.      * anchorIndex.
  282.      * @param {number} index New value for leadIndex or anchorIndex.
  283.      * @return {number} Corrected value.
  284.      */
  285.     adjustIndex_: function(index) {
  286.       index = Math.max(-1, Math.min(this.length_ - 1, index));
  287.       // On Mac and ChromeOS lead and anchor items are forced to be among
  288.       // selected items. This rule is not enforces until end of batch update.
  289.       if (!this.changeCount_ && !this.independentLeadItem_ &&
  290.           !this.getIndexSelected(index)) {
  291.         index = this.lastSelectedIndex;
  292.       }
  293.       return index;
  294.     },
  295.  
  296.     /**
  297.      * Whether the selection model supports multiple selected items.
  298.      * @type {boolean}
  299.      */
  300.     get multiple() {
  301.       return true;
  302.     },
  303.  
  304.     /**
  305.      * Adjusts the selection after reordering of items in the table.
  306.      * @param {!Array.<number>} permutation The reordering permutation.
  307.      */
  308.     adjustToReordering: function(permutation) {
  309.       this.beginChange();
  310.       var oldLeadIndex = this.leadIndex;
  311.       var oldAnchorIndex = this.anchorIndex;
  312.  
  313.       this.selectedIndexes = this.selectedIndexes.map(function(oldIndex) {
  314.         return permutation[oldIndex];
  315.       }).filter(function(index) {
  316.         return index != -1;
  317.       });
  318.  
  319.       // Will be adjusted in endChange.
  320.       if (oldLeadIndex != -1)
  321.         this.leadIndex = permutation[oldLeadIndex];
  322.       if (oldAnchorIndex != -1)
  323.         this.anchorIndex = permutation[oldAnchorIndex];
  324.       this.endChange();
  325.     },
  326.  
  327.     /**
  328.      * Adjusts selection model length.
  329.      * @param {number} length New selection model length.
  330.      */
  331.     adjustLength: function(length) {
  332.       this.length_ = length;
  333.     }
  334.   };
  335.  
  336.   return {
  337.     ListSelectionModel: ListSelectionModel
  338.   };
  339. });
  340.